package com.applet.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.applet.constant.JwtClaimsConstant;
import com.applet.constant.MessageConstant;
import com.applet.dto.UserLoginDTO;
import com.applet.entity.User;
import com.applet.exception.LoginFailedException;
import com.applet.properties.JwtProperties;
import com.applet.properties.WeChatProperties;
import com.applet.user.mapper.UserMapper;
import com.applet.user.service.UserService;
import com.applet.utils.HttpClientUtil;
import com.applet.utils.JwtUtil;
import com.applet.vo.UserLoginVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 微信的用户 serviceImpl
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {


    @Value("${sky.wechat.openIdUrl}")
    private String wxOpenidUrl;

    //token令牌
    @Resource
    private JwtProperties jwtProperties;

    //微信服务调用获取openid
    @Resource
    private WeChatProperties weChatProperties;

    @Resource
    private UserMapper userMapper;






    /**
     * C端
     *        用户登录
     * @param userLoginDTO
     */
    @Override
    public UserLoginVO wxLogin(UserLoginDTO userLoginDTO) {

        // 1.封装请求微信服务的参数
        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("appid", weChatProperties.getAppid());
        paramsMap.put("secret", weChatProperties.getSecret());
        paramsMap.put("js_code", userLoginDTO.getCode());
        paramsMap.put("grant_type", "authorization_code");

        // 2.请求微信服务 获取openid
        String resultStr = HttpClientUtil.doGetHasParamsResponseJson(wxOpenidUrl, paramsMap);
        log.info("请求微信服务获取openid,返回数据: {}", resultStr);
        // 转为JSONObject <==> Map:{session_key:"xxx",openid:"xxx"}
        JSONObject resultData = JSONObject.parseObject(resultStr);

        // 3.判断返回结果  错误则抛出异常
        if( CollectionUtils.isEmpty(resultData) && !StringUtils.hasLength(resultData.getString("openid"))){
            //微信返回错误 抛出异常
            throw new LoginFailedException(MessageConstant.WX_LOGON_ERROR);
        }

        // 4.根据返回的openid查询本项目数据库，判断是否是新用户
        String openid = resultData.getString("openid");
        User user = userMapper.selectUserByOpenId(openid);

        // 5.判断是否是新用户, 新用户自动注册,保存本系统数据库用户信息
        if(Objects.isNull(user)){
            user = User.builder().openid(openid).createTime(LocalDateTime.now()).build();
            Integer userCount = userMapper.insert(user);
            log.info("openid: {},新用户注册，影响行数: {}", openid, userCount);
        }

        // 6.封装token参数
        Map<String, Object> claims = new HashMap<>();
        claims.put(JwtClaimsConstant.USER_ID, user.getId());
        // 7.生成token
        String jwtToken = JwtUtil.createToken(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);

        // 8.返回
        UserLoginVO userLoginVO = UserLoginVO.builder().id(user.getId()).openid(openid).token("Bearer " + jwtToken).build();
        return userLoginVO;
    }



    /**
     * C端
     *        根据id查询用户
     * @param userId
     */
    @Override
    public User getById(Long userId) {
        return userMapper.getById(userId);
    }


}
